home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
video
/
zapem-0.000
/
zapem-0
/
zapem
/
sprite.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-03
|
7KB
|
383 lines
/* Copyright Alex Hornby 1994/1995. All rights reserved.
See file README for details
*/
/* C++ code for sprite block copy wrapper */
#include <SLList.h>
#include <assert.h>
#include <vga.h>
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include "btypes.h"
#include "palette.h"
#include "sprite.h"
#include "asmblock.h"
#include "gif.h"
#include "alopen.h"
extern Palette gamepal;
/* Static data members */
SLList<Sprite*> Sprite :: vlist;
SLList<Sprite*> Sprite :: appearlist;
SLList<Sprite*> Sprite :: disappearlist;
/***************************************************************************
LET THE FUNCTIONS BEGIN!
****************************************************************************/
Sprite::~Sprite()
{
if( backmem!=0) delete backmem;
if (visibleflag==true) setVisible(false);
}
Sprite::Sprite() : Animation(), Screen()
{
visibleflag=false;
backmem=0;
}
void
Sprite::copy( const Sprite& s)
{
xp=s.xp;
yp=s.yp;
oldxp=s.oldxp;
oldyp=s.oldyp;
deltax=s.deltax;
deltay=s.deltay;
setVisible(s.getVisible());
if(backmem!=0)
delete [] backmem;
backmem=new byte [ByteLength];
if(s.backmem!=0)
memcpy(backmem, s.backmem, ByteLength);
}
Sprite::Sprite( const Sprite& s) : Animation(s), Screen(s)
{
copy(s);
}
Sprite&
Sprite::operator=( const Sprite& s)
{
if( &s != this)
{
Animation::operator=(s);
Screen::operator=(s);
copy(s);
}
return *this;
}
/* Load the single sprite gif file int sprite bank slot */
/* Yuck! */
void
Sprite :: gifLoadAndCut(char *filename, int slot)
{
FILE *fp=alopen(filename, "rb");
Gif gif;
Palette gifpal;
gif.Load(fp);
gifpal.scan(gif.getPtr(), gif.getWidth()*gif.getHeight());
gif.SetPalette(gifpal);
gamepal.remap(gif.getPtr(), gif.getWidth()*gif.getHeight() , gifpal);
// Save the old screen settings
pixel *oldgmem=getGraphMem();
int oldswidth=getScreenWidth();
int oldsheight=getScreenHeight();
// Set the screen up to the same size as the picture
setGraphMem(gif.getPtr());
setScreenWidth(gif.getWidth());
setScreenHeight(gif.getHeight());
// Cut the sprite
Cut(0, 0, gif.getWidth(), gif.getHeight(), slot);
// Restore the screen settings
setGraphMem(oldgmem);
setScreenHeight(oldsheight);
setScreenWidth(oldswidth);
}
/* Have we collided with something? */
bool
Sprite :: collide(const Sprite& s)
{
int xd=s.getXp()-getXp();
int yd=s.getYp()-getYp();
if( (xd< getWidth() && xd > -s.getWidth() ) &&
(yd< getHeight() && yd > -s.getHeight()) )
return true;
else
return false;
}
void
Sprite :: setSlot(int slot)
{
assert(slot<MAXFRAME);
assert(slot>=0);
curslot=slot;
blockmem=sprbank[slot].block;
maskmem=sprbank[slot].mask;
width=sprbank[slot].width;
height=sprbank[slot].height;
ByteLength=sprbank[slot].ByteLength;
}
void
Sprite :: appear(void)
{
Sprite *x=this;
appearlist.append(x);
}
void
Sprite :: disappear(void)
{
Sprite *x=this;
disappearlist.append(x);
}
void
Sprite :: setVisible( bool v)
{
if( v==true)
{
if(visibleflag==false)
{
visibleflag=true;
vlist.append(this);
}
}
else
{
Pix here, prev=0;
if(visibleflag==true)
{
for(here=vlist.first(); here!=0; vlist.next(here))
{
if(vlist(here)==this)
{
if(here==vlist.first())
vlist.del_front();
else
vlist.del_after(prev);
here=0;
}
prev=here;
}
}
visibleflag=false;
}
}
void
Sprite :: Cut ( uint32 x1, uint32 y1, uint32 xw, uint32 yw, int slot)
{
curslot=slot;
/* Make the slot equal our new graphic. There should really be
some checking to see if the slot is already in use */
sprbank[slot].width=width=xw;
sprbank[slot].height=height=yw;
sprbank[slot].ByteLength=ByteLength=xw*yw;
xp=x1;yp=y1;
/* if memory in use then free it. This is extremely dodgy! */
if( backmem!=0 ) delete backmem;
/* reserve block memory */
blockmem=new byte [ByteLength];
maskmem=new byte [ByteLength];
backmem=new byte [ByteLength];
sprbank[slot].block=blockmem;
sprbank[slot].mask=maskmem;
/* call assembly routines */
cutblocknew( getGraphMem()+x1+(y1*getScreenWidth()), blockmem, getScreenWidth(), width, height);
cutblocknew( getGraphMem()+x1+(y1*getScreenWidth()), backmem, getScreenWidth(), width, height);
MakeMask();
}
void
Sprite :: MakeMask(byte maskcolour)
{
uint32 count;
byte *maskptr, *blockptr;
maskptr=maskmem;
blockptr=blockmem;
for( count=0; count<ByteLength; count++)
{
if(*blockptr==maskcolour)
*maskptr=255;
else
*maskptr=0;
maskptr++;
blockptr++;
}
}
void
Sprite :: Recut( uint32 x1, uint32 y1)
{
/* call assembly routine */
cutblock( getGraphMem()+x1+(y1*getScreenWidth()), blockmem, width, height);
MakeMask();
}
void
Sprite :: Paste( uint32 x1, uint32 y1)
{
/* Straight into the assembly bit */
pasteblock( blockmem, getGraphMem()+x1+(y1*getScreenWidth()), width, height );
}
void
Sprite :: getBack( uint32 x1, uint32 y1)
{
xp=oldxp=x1;yp=oldyp=y1;
/* get new background */
if(backmem==0) backmem=new byte[ByteLength];
cutblock( getGraphMem()+xp+(yp*getScreenWidth()),backmem, width, height );
}
void
Sprite :: ReplaceAll(void)
{
Pix cur, n; // n is needed because of animation can cause NULL pix
cur=vlist.first();
assert(cur!=0);
while( cur!=0 )
{
vlist(cur)->fixBack();
n=cur;
vlist.next(n);
if( vlist(cur)->getAnim()==true)
vlist(cur)->doAnim();
cur=n;
}
cur=disappearlist.first();
while(cur!=0)
{
disappearlist(cur)->setVisible(false);
disappearlist.next(cur);
}
while(!disappearlist.empty())
{
disappearlist.remove_front();
}
}
void
Sprite :: PasteAll(void)
{
Pix cur=vlist.first();
while( cur!=0 )
{
vlist(cur)->Transpaste();
vlist.next(cur);
}
}
void
Sprite :: UpdateAll(void)
{
ReplaceAll();
PasteAll();
}
void
Sprite :: hideAll(void)
{
Pix cur, n; // n is needed because of animation can cause NULL pix
cur=vlist.first();
while( cur!=0 )
{
n=cur;
vlist.next(n);
vlist(cur)->setVisible(false);
cur=n;
}
}
void
Sprite :: Update( int x1, int y1)
{
xp=x1;yp=y1;
// replace old bit
pasteblock( backmem, getGraphMem()+oldxp+(oldyp*getScreenWidth()), width, height );
// get new background
cutblock( getGraphMem()+xp+(yp*getScreenWidth()),backmem, width, height );
// display sprite
Transpaste();
}
void
Sprite :: Transpaste( void)
{
/*
andpasteblock( maskmem, getGraphMem()+xp+(yp*getScreenWidth()), width, height );
xorpasteblock( blockmem, getGraphMem()+xp+(yp*getScreenWidth()), width, height );
*/
transpasteblock( blockmem, maskmem, getGraphMem()+xp+(yp*getScreenWidth()), width, height );
oldxp=xp;oldyp=yp;
}
void
Sprite::getAll()
{
Pix cur=appearlist.first();
while(cur!=0)
{
appearlist(cur)->setVisible(true);
appearlist(cur)->getBack();
appearlist.next(cur);
}
while(!appearlist.empty())
{
appearlist.remove_front();
}
cur=vlist.first();
while( cur!=0 )
{
vlist(cur)->CutBack();
vlist.next(cur);
}
}
void
Sprite :: fixBack( void )
{
// replace old bit
pasteblock( backmem, getGraphMem()+oldxp+(oldyp*getScreenWidth()), width, height );
}
void
Sprite :: CutBack( void)
{
// get new background
cutblock( getGraphMem()+xp+(yp*getScreenWidth()),backmem, width, height );
}